// wglapplayerdebug.cpp
//

#include "wgl/wgl_gl.hpp"
#include "wgl/wglapplayerdebug.hpp"

using namespace wgl;

#include "wgl/wglapplayerdebug.inl.cpp"



template<>
const AppLayerLoaderID AppLayerLoaderImpl<AppLayerLoaderDebug>::LOADER_ID
= AppLayerLoader::register_loader<AppLayerLoaderDebug>("WGL_LAYER_debug");



struct AppLayerVTableVirtualDebug : public AppLayerVTableVirtual
{
  bool in_begin{false};
  
  virtual void pre_call ( AppLayer &layer,
                          AppLayerFuncID func_id,
                          ... )
  {
    // const AppLayerFuncInfos &infos = WGL_GET_APP_LAYER_FUNC_INFOS(func_id);
    // WGL_TRACE("gl pre-call: %s (%lu)", infos.name, WGL_ENUM_VALUE(func_id));

    if (func_id == AppLayerFuncID::fGlBegin)
      {
        WGL_ASSERT(!in_begin);
        in_begin = true;
      }
    else
      {
      }
  }
  
  virtual void post_call ( AppLayer &layer,
                           AppLayerFuncID func_id,
                           ... )
  {
    const AppLayerFuncInfos &infos = WGL_GET_APP_LAYER_FUNC_INFOS(func_id);
    // WGL_TRACE("gl post-call: %s (%lu)", infos.name, WGL_ENUM_VALUE(func_id));

    if (func_id == AppLayerFuncID::fGlEnd)
      {
        WGL_ASSERT(in_begin);
        in_begin = false;
      }

    if (!(in_begin || func_id == AppLayerFuncID::fGlGetError))
      {
        int n_errs = 0;
        GLenum err;
        while ((err = layer.vtable.GetError()) != GL_NO_ERROR)
          {
            WGL_ERROR("GL error: %s: %s", infos.func_name, gl_error_name(err));
            ++n_errs;
          }
        if (n_errs > 0)
          {
            WGL_FATAL("%d GL errors", n_errs);
          }
      }
  }
};



// AppLayerLoaderDebug::load_layer
//
void AppLayerLoaderDebug::load_layer ( AppLayer &layer )
{
  AppLayerVTableVirtual *vt_virt = new AppLayerVTableVirtualDebug;
  layer.data = vt_virt;
  DebugLayerVTableLoader::load_vtable(layer.vtable);
}
